package ui.helpers;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

import core.Database;
import core.DatabaseTable;
import core.TableColumn;
import java.util.Enumeration;
import javax.swing.text.Position;
import javax.swing.tree.TreePath;

import org.apache.log4j.Logger;

/**
 * The tree-diagram used to display the information of the database and the
 * elements contained
 *
 * @author Sakis Vtdk <sakis.vtdk@gmail.com>
 */
public class DatabaseTree extends JTree
{
	private DatabaseTree(DefaultMutableTreeNode rootNode)
	{
		super(rootNode);
	}
	
	public static DatabaseTree getDatabaseTree()
	{
		if(_instance == null)
		{
			_instance = new DatabaseTree(DatabaseTree.buildTreeNode());
		}

		return _instance;
	}

	private static void updateInstance(DefaultMutableTreeNode rootNode)
	{
		_instance = new DatabaseTree(rootNode);
	}

	public static DefaultMutableTreeNode buildTreeNode()
	{
		DefaultMutableTreeNode dbNode = new DefaultMutableTreeNode(Database.getDatabase().getDatabaseName());
		DefaultMutableTreeNode tableNode = null;
		DefaultMutableTreeNode columnNode = null;

		for(DatabaseTable dbTable : Database.getDatabase().getTables())
		{
			tableNode = new DefaultMutableTreeNode(dbTable.getName());
			for(TableColumn dbColumn : dbTable.getColumns())
			{
				columnNode = new DefaultMutableTreeNode(dbColumn.getName() +" ("+ dbColumn.getDataType(true) +", Default: "+ dbColumn.getDefaultValue() +")");
				tableNode.add(columnNode);
			}
			dbNode.add(tableNode);
		}

		//when a change is made, update the instance as well
		updateInstance(dbNode);

		return dbNode;
	}

	public static TreePath findNode(String nodeName)
	{
		TreePath path = null;

		if(nodeName != null && !nodeName.isEmpty())
		{
			log.trace("Starting search for "+ nodeName);
			DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) _instance.getModel().getRoot();
			log.trace("Root node: "+ rootNode.toString());
			
			//searching the tree level-based
			Enumeration<DefaultMutableTreeNode> searchEnumeration = rootNode.breadthFirstEnumeration();

			while(searchEnumeration.hasMoreElements())
			{
				DefaultMutableTreeNode node = searchEnumeration.nextElement();
				log.trace("Node trying to match: "+ node.toString());
				if(node.getUserObject().toString().equalsIgnoreCase(nodeName))
				{
					path = new TreePath(node.getPath());
					break;
				}
				else if(node.getUserObject().toString().startsWith(nodeName))
				{
					path = new TreePath(node.getPath());
				}
			}
		}

		return path;
	}

	
	private static DatabaseTree _instance = null;
	private static Logger log = Logger.getLogger(DatabaseTree.class);
}
